
package com.phevos.web.cas.proxy;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.phevos.web.cas.util.SecureURL;

public class ProxyTicketReceptor extends HttpServlet
{

    // *********************************************************************
    // Constants

    /**
     * 
     */
    private static final long serialVersionUID = -6838130400542984815L;

    private static final String PGT_IOU_PARAM = "pgtIou";

    private static final String PGT_ID_PARAM = "pgtId";

    // *********************************************************************
    // Private state

    private static Map pgt;

    private static String casProxyUrl;

    // *********************************************************************
    // Initialization
    /**
     * init
     * 
     * @param config ServletConfig
     * @throws ServletException
     */
    public void init(ServletConfig config) throws ServletException
    {
        super.init(config);
        synchronized (ProxyTicketReceptor.class)
        {
            if (pgt == null)
                pgt = new HashMap();

            // retrieve the URL for CAS
            if (casProxyUrl == null)
            {
                ServletContext app = config.getServletContext();
                casProxyUrl = (String)app.getInitParameter("edu.yale.its.tp.cas.proxyUrl");
                if (casProxyUrl == null)
                    throw new ServletException("need edu.yale.its.tp.cas.proxyUrl");
            }
        }
    }

    // *********************************************************************
    // Request handling
    /**
     * do post
     * 
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     * @throws ServletException
     * @throws IOException
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        doGet(request, response);
    }

    /**
     * do get
     * 
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     * @throws ServletException
     * @throws IOException
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        String pgtId = request.getParameter(PGT_ID_PARAM);
        String pgtIou = request.getParameter(PGT_IOU_PARAM);
        if (pgtId != null && pgtIou != null)
        {
            synchronized (pgt)
            {
                pgt.put(pgtIou, pgtId);
            }
        }
        PrintWriter out = response.getWriter();
        out.println("<casClient:proxySuccess " + "xmlns:casClient=\"http://www.yale.edu/tp/casClient\"/>");
        out.flush();
    }

    // *********************************************************************
    // Interface to package members

    // NOTE: PUBLIC FOR THE MOMENT

    /**
     * Retrieves a proxy ticket using the PGT that corresponds to the given PGT IOU.
     */
    public static String getProxyTicket(String pgtIou, String target) throws IOException
    {
        synchronized (ProxyTicketReceptor.class)
        {
            // ensure state is sensible
            if (casProxyUrl == null || pgt == null)
                throw new IllegalStateException("getProxyTicket() only works after servlet has been initialized");
        }

        // retrieve PGT
        String pgtId = null;
        synchronized (pgt)
        {
            pgtId = (String)pgt.get(pgtIou);
        }
        if (pgtId == null)
            return null;

        // retrieve an XML response from CAS's "Proxy" actuator
        String url = casProxyUrl + "?pgt=" + pgtId + "&targetService=" + target;
        String response = SecureURL.retrieve(url);

        // parse this response (use a lightweight approach for now)
        if (response.indexOf("<cas:proxySuccess>") != -1 && response.indexOf("<cas:proxyTicket>") != -1)
        {
            int startIndex = response.indexOf("<cas:proxyTicket>") + "<cas:proxyTicket>".length();
            int endIndex = response.indexOf("</cas:proxyTicket>");
            return response.substring(startIndex, endIndex);
        }
        else
        {
            // generic failure
            return null;
        }
    }
}
